/*===========================================================================*/
/**
 * @file hal_canfd.c
 *
 * @brief Implementation for CAN FD HAL driver.
 *
 *------------------------------------------------------------------------------
 *
 * Copyright (C) 2025 Aptiv. All rights reserved.
 * Aptiv Sensitve Business - Restricted Aptiv information. Do not disclose
 *
 *------------------------------------------------------------------------------
 *
 * @section DESC DESCRIPTION:
 *   - See header for full description.
 *
 * @section ABBR ABBREVIATIONS:
 *   - MCAN: Modular CAN (CAN FD)
 *
 * @section TRACE TRACEABILITY INFO:
 *   - Design Document(s):
 *     - CAN FD HAL Design Spec v1.0
 *   - Requirements Document(s):
 *     - See System Integration Spec Section 3.4
 *   - Applicable Standards:
 *     - ESGW_4-2_PE-SWx_00-01-A02_EN - C Coding Standards [20120506]
 *
 * @section DFS DEVIATIONS FROM STANDARDS:
 *   - None.
 */
/*==========================================================================*/

/*===========================================================================*
 * Standard Header Files
 *===========================================================================*/
#include "hal_canfd.h"
#include <string.h>

/*===========================================================================*
 * Other Header Files
 *===========================================================================*/
#include "hal_gpio.h"
#include "device.h"  // 需要DEVICE_GPIO_CFG_MCANRXA等宏
#include "driverlib.h"


/*===========================================================================*
 * Local Preprocessor #define Constants
 *===========================================================================*/

/*===========================================================================*
 * Local Preprocessor #define MACROS
 *===========================================================================*/

/*===========================================================================*
 * Local Type Declarations
 *===========================================================================*/

/*===========================================================================*
 * Exported Object Definitions
 *===========================================================================*/

/*===========================================================================*
 * Local Object Definitions
 *===========================================================================*/
static MCAN_TxBufElement s_txMsg;  // 仅作示例，生产环境请做buffer管理
static MCAN_RxBufElement s_rxMsg;   // 定义接收缓存（全局/静态）
/*===========================================================================*
 * Local Function Prototypes
 *===========================================================================*/

/*===========================================================================*
 * Local Inline Function Definitions and Function-Like Macros
 *===========================================================================*/

/*===========================================================================*
 * Function Definitions
 *===========================================================================*/

void hal_canfd_set_clk_div(Hal_Canfd_Clk_Div_T div)
{
    switch (div) {
        case HAL_CANFD_CLK_DIV_1:
            SysCtl_setMCANClk(SYSCTL_MCANCLK_DIV_1);
            break;
        case HAL_CANFD_CLK_DIV_2:
            SysCtl_setMCANClk(SYSCTL_MCANCLK_DIV_2);
            break;
        case HAL_CANFD_CLK_DIV_3:
            SysCtl_setMCANClk(SYSCTL_MCANCLK_DIV_3);
            break;
        case HAL_CANFD_CLK_DIV_4:
            SysCtl_setMCANClk(SYSCTL_MCANCLK_DIV_4);
            break;
        default:
            // 参数不支持，可加断言或日志
            break;
    }
}


void hal_canfd_gpio_init(void)
{
    hal_gpio_set_pinmux(DEVICE_GPIO_CFG_MCANRXA);
    hal_gpio_set_pinmux(DEVICE_GPIO_CFG_MCANTXA);
}


bool hal_canfd_init(const Hal_Canfd_Config_T* cfg)
{
    MCAN_InitParams initParams = {0};
    MCAN_MsgRAMConfigParams msgRAMConfigParams = {0};

#define NUM_OF_MSG                      (1U)
#define MCAN_STD_ID_FILTER_NUM          (1U)  // 改成1 配置1个标准过滤器
#define MCAN_EXT_ID_FILTER_NUM          (0U)
#define MCAN_FIFO_0_NUM                 (0U)
#define MCAN_FIFO_0_ELEM_SIZE           (MCAN_ELEM_SIZE_64BYTES)
#define MCAN_FIFO_1_NUM                 (0U)
#define MCAN_FIFO_1_ELEM_SIZE           (MCAN_ELEM_SIZE_64BYTES)
#define MCAN_RX_BUFF_NUM                (1U)  // 改成1 配置1个Rx Buffer
#define MCAN_RX_BUFF_ELEM_SIZE          (MCAN_ELEM_SIZE_64BYTES)
#define MCAN_TX_BUFF_SIZE               (NUM_OF_MSG)
#define MCAN_TX_FQ_SIZE                 (0U)
#define MCAN_TX_BUFF_ELEM_SIZE          (MCAN_ELEM_SIZE_8BYTES)
#define MCAN_TX_EVENT_SIZE              (0U)

#define MCAN_STD_ID_FILT_START_ADDR     (0x0U)
#define MCAN_EXT_ID_FILT_START_ADDR     (MCAN_STD_ID_FILT_START_ADDR + ((MCAN_STD_ID_FILTER_NUM * MCANSS_STD_ID_FILTER_SIZE_WORDS * 4U)))
#define MCAN_FIFO_0_START_ADDR          (MCAN_EXT_ID_FILT_START_ADDR + ((MCAN_EXT_ID_FILTER_NUM * MCANSS_EXT_ID_FILTER_SIZE_WORDS * 4U)))
#define MCAN_FIFO_1_START_ADDR          (MCAN_FIFO_0_START_ADDR + (MCAN_getMsgObjSize(MCAN_FIFO_0_ELEM_SIZE) * 4U * MCAN_FIFO_0_NUM))
#define MCAN_RX_BUFF_START_ADDR         (MCAN_FIFO_1_START_ADDR + (MCAN_getMsgObjSize(MCAN_FIFO_1_ELEM_SIZE) * 4U * MCAN_FIFO_1_NUM))
#define MCAN_TX_BUFF_START_ADDR         (MCAN_RX_BUFF_START_ADDR + (MCAN_getMsgObjSize(MCAN_RX_BUFF_ELEM_SIZE) * 4U * MCAN_RX_BUFF_NUM))
#define MCAN_TX_EVENT_START_ADDR        (MCAN_TX_BUFF_START_ADDR + (MCAN_getMsgObjSize(MCAN_TX_BUFF_ELEM_SIZE) * 4U * (MCAN_TX_BUFF_SIZE + MCAN_TX_FQ_SIZE)))



    MCAN_BitTimingParams bitTimes = {0};

    // 基本功能配置
    initParams.fdMode = cfg->fd_enable ? 1U : 0U;
    initParams.brsEnable = cfg->brs_enable ? 1U : 0U;

    // Bit Timing配置
    bitTimes.nomRatePrescalar  = cfg->nominal.prescaler;
    bitTimes.nomTimeSeg1       = cfg->nominal.tseg1;
    bitTimes.nomTimeSeg2       = cfg->nominal.tseg2;
    bitTimes.nomSynchJumpWidth = cfg->nominal.sjw;

    // ------ 填充msgRAMConfigParams字段 --------
    msgRAMConfigParams.txStartAddr      = MCAN_TX_BUFF_START_ADDR;
    msgRAMConfigParams.txBufNum         = MCAN_TX_BUFF_SIZE;
    msgRAMConfigParams.txBufMode        = 0U;
    msgRAMConfigParams.txBufElemSize    = MCAN_TX_BUFF_ELEM_SIZE;

    // ==== 新增Rx Buffer相关 ====
    msgRAMConfigParams.rxBufStartAddr   = MCAN_RX_BUFF_START_ADDR;
    msgRAMConfigParams.rxBufElemSize    = MCAN_RX_BUFF_ELEM_SIZE;


    // ==== 新增标准过滤器相关 ====
    msgRAMConfigParams.flssa            = MCAN_STD_ID_FILT_START_ADDR;
    msgRAMConfigParams.lss              = MCAN_STD_ID_FILTER_NUM;

    // ==== 其它保留为0 ====

    // 内存初始化
    while(FALSE == MCAN_isMemInitDone(cfg->base_addr)) {}

    // 软件初始化模式
    MCAN_setOpMode(cfg->base_addr, MCAN_OPERATION_MODE_SW_INIT);
    while (MCAN_OPERATION_MODE_SW_INIT != MCAN_getOpMode(cfg->base_addr)) {}

    // 初始化模块
    MCAN_init(cfg->base_addr, &initParams);

    // Bit timing
    MCAN_setBitTime(cfg->base_addr, &bitTimes);

    // RAM区配置
    MCAN_msgRAMConfig(cfg->base_addr, &msgRAMConfigParams);

    // ==== 配置标准过滤器，只允许你的物理寻址ID通过 ====
    MCAN_StdMsgIDFilterElement stdFiltelem = {0};
    stdFiltelem.sfid1 = cfg->rx_id;            // 你的UDS物理寻址ID（如0x7E0）
    stdFiltelem.sfec  = MCAN_STDFILTEC_RXBUFF; // 命中则放Rx Buffer
    stdFiltelem.sft   = MCAN_STDFILT_CLASSIC;  // 经典方式
    MCAN_addStdMsgIDFilter(cfg->base_addr, 0, &stdFiltelem);

    // 退出初始化模式
    MCAN_setOpMode(cfg->base_addr, MCAN_OPERATION_MODE_NORMAL);
    while (MCAN_OPERATION_MODE_NORMAL != MCAN_getOpMode(cfg->base_addr)) {}

    return true;
}

bool hal_canfd_transmit(uint32_t id, const uint8_t *data, uint8_t len, bool ext_id)
{
    memset(&s_txMsg, 0, sizeof(s_txMsg));
    s_txMsg.id   = id;
    s_txMsg.rtr  = 0U;
    s_txMsg.xtd  = ext_id ? 1U : 0U;
    s_txMsg.dlc  = len;
    s_txMsg.efc  = 1U; // Event FIFO Control
    memcpy(s_txMsg.data, data, len);

    MCAN_writeMsgRam(MCANA_DRIVER_BASE, MCAN_MEM_TYPE_BUF, 0, &s_txMsg);
    MCAN_txBufAddReq(MCANA_DRIVER_BASE, 0U);

    // 等待发送完成（实际工程可异步优化）
    while(MCAN_getTxBufReqPend(MCANA_DRIVER_BASE)) {}

    return true;
}

bool hal_canfd_receive(uint32_t *id, uint8_t *data, uint8_t *len, bool *ext_id)
{
    MCAN_RxNewDataStatus newData;
    MCAN_getNewDataStatus(MCANA_DRIVER_BASE, &newData);

    // 只用Rx Buffer 0，所以检查statusLow的最低位
    if ((newData.statusLow & 0x1) == 0) {
        return false; // 没有新消息
    }

    MCAN_readMsgRam(MCANA_DRIVER_BASE, MCAN_MEM_TYPE_BUF, 0, 0, &s_rxMsg);
    MCAN_clearNewDataStatus(MCANA_DRIVER_BASE, &newData);

    if (id)     *id    = s_rxMsg.id;
    if (data)   memcpy(data, s_rxMsg.data, s_rxMsg.dlc);
    if (len)    *len   = s_rxMsg.dlc;
    if (ext_id) *ext_id = s_rxMsg.xtd ? true : false;

    return true;
}

/*============================================================================*\
 * AUTHOR(S) IDENTITY (AID)
 *-----------------------------------------------------------------------------
 *  XG   Xianzhi Gong   njp4bz
\*============================================================================*/

/*============================================================================*\
 * FILE REVISION HISTORY
 *-----------------------------------------------------------------------------
 *  DATE        REVISION   AID   JIRA Ticket ID/SUMMARY OF CHANGES
 *  ---------------------------------------------------------------------------
 *  2025-05-28  1.00       XG    Initial version
 *  ---------------------------------------------------------------------------
\*============================================================================*/

/* END OF FILE -------------------------------------------------------------- */
